home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / cosmic.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  12KB  |  528 lines

  1. /***************************************************************************
  2.  
  3.  COSMIC.C
  4.  
  5.  emulation of video hardware of cosmic machines of 1979-1980(ish)
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13. static int refresh_tmpbitmap;
  14. static int flipscreen;
  15. static int (*map_color)(int x, int y);
  16.  
  17. static int color_registers[3];
  18. static int color_base = 0;
  19. static int nomnlnd_background_on=0;
  20.  
  21.  
  22. /* No Mans Land - I don't know if there are more screen layouts than this */
  23. /* this one seems to be OK for the start of the game       */
  24.  
  25. static const signed short nomnlnd_tree_positions[2][2] =
  26. {
  27.     {66,63},{66,159}
  28. };
  29.  
  30. static const signed short nomnlnd_water_positions[4][2] =
  31. {
  32.     {160,32},{160,96},{160,128},{160,192}
  33. };
  34.  
  35.  
  36. WRITE_HANDLER( panic_color_register_w )
  37. {
  38.     /* 7c0c & 7c0e = Rom Address Offset
  39.         7c0d        = high / low nibble */
  40.  
  41.     if (color_registers[offset] != (data & 0x80))
  42.     {
  43.         color_registers[offset] = data & 0x80;
  44.         color_base = (color_registers[0] << 2) + (color_registers[2] << 3);
  45.         refresh_tmpbitmap = 1;
  46.     }
  47. }
  48.  
  49. WRITE_HANDLER( cosmicg_color_register_w )
  50. {
  51.     if (color_registers[offset] != data)
  52.     {
  53.         color_registers[offset] = data;
  54.  
  55.         color_base = 0;
  56.  
  57.         if (color_registers[0] == 1) color_base += 0x100;
  58.         if (color_registers[1] == 1) color_base += 0x200;
  59.  
  60.         refresh_tmpbitmap = 1;
  61.     }
  62. }
  63.  
  64.  
  65. static int panic_map_color(int x, int y)
  66. {
  67.     /* 8 x 16 coloring */
  68.     unsigned char byte = memory_region(REGION_USER1)[color_base + (x / 16) * 32 + (y / 8)];
  69.  
  70.     if (color_registers[1])
  71.         return byte >> 4;
  72.     else
  73.         return byte & 0x0f;
  74. }
  75.  
  76. WRITE_HANDLER( panic_flipscreen_w )
  77. {
  78.     /* Only single bit seems to be used for this */
  79.  
  80.     if (data != flipscreen)
  81.     {
  82.         flipscreen = data & 0x80;
  83.         refresh_tmpbitmap = 1;
  84.     }
  85. }
  86.  
  87. static int cosmicg_map_color(int x, int y)
  88. {
  89.     unsigned char byte;
  90.  
  91.     /* 16 x 16 coloring */
  92.     byte = memory_region(REGION_USER1)[color_base + (y / 16) * 16 + (x / 16)];
  93.  
  94.     /* the upper 4 bits are for cocktail mode support */
  95.  
  96.     return byte & 0x0f;
  97. }
  98.  
  99. static int magspot2_map_color(int x, int y)
  100. {
  101.     unsigned char byte;
  102.  
  103.     /* 16 x 8 coloring */
  104.  
  105.     // Should the top line of the logo be red or white???
  106.  
  107.     byte = memory_region(REGION_USER1)[(x / 8) * 16 + (y / 16)];
  108.  
  109.     if (color_registers[1])
  110.         return byte >> 4;
  111.     else
  112.         return byte & 0x0f;
  113. }
  114.  
  115.  
  116. static const unsigned char panic_remap_sprite_code[64][2] =
  117. {
  118. {0x00,0},{0x26,0},{0x25,0},{0x24,0},{0x23,0},{0x22,0},{0x21,0},{0x20,0}, /* 00 */
  119. {0x00,0},{0x26,0},{0x25,0},{0x24,0},{0x23,0},{0x22,0},{0x21,0},{0x20,0}, /* 08 */
  120. {0x00,0},{0x16,0},{0x15,0},{0x14,0},{0x13,0},{0x12,0},{0x11,0},{0x10,0}, /* 10 */
  121. {0x00,0},{0x16,0},{0x15,0},{0x14,0},{0x13,0},{0x12,0},{0x11,0},{0x10,0}, /* 18 */
  122. {0x00,0},{0x06,0},{0x05,0},{0x04,0},{0x03,0},{0x02,0},{0x01,0},{0x00,0}, /* 20 */
  123. {0x00,0},{0x06,0},{0x05,0},{0x04,0},{0x03,0},{0x02,0},{0x01,0},{0x00,0}, /* 28 */
  124. {0x07,2},{0x06,2},{0x05,2},{0x04,2},{0x03,2},{0x02,2},{0x01,2},{0x00,2}, /* 30 */
  125. {0x07,2},{0x06,2},{0x05,2},{0x04,2},{0x03,2},{0x02,2},{0x01,2},{0x00,2}, /* 38 */
  126. };
  127.  
  128. /*
  129.  * Panic Color table setup
  130.  *
  131.  * Bit 0 = RED, Bit 1 = GREEN, Bit 2 = BLUE
  132.  *
  133.  * First 8 colors are normal intensities
  134.  *
  135.  * But, bit 3 can be used to pull Blue via a 2k resistor to 5v
  136.  * (1k to ground) so second version of table has blue set to 2/3
  137.  *
  138.  */
  139.  
  140. void panic_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  141. {
  142.     int i;
  143.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  144.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  145.  
  146.     for (i = 0;i < Machine->drv->total_colors;i++)
  147.     {
  148.         *(palette++) = 0xff * ((i >> 0) & 1);
  149.         *(palette++) = 0xff * ((i >> 1) & 1);
  150.         if ((i & 0x0c) == 0x08)
  151.             *(palette++) = 0xaa;
  152.         else
  153.             *(palette++) = 0xff * ((i >> 2) & 1);
  154.     }
  155.  
  156.  
  157.     for (i = 0;i < TOTAL_COLORS(0);i++)
  158.         COLOR(0,i) = *(color_prom++) & 0x0f;
  159.  
  160.  
  161.     map_color = panic_map_color;
  162. }
  163.  
  164.  
  165. /*
  166.  * Cosmic Alien Color table setup
  167.  *
  168.  * 8 colors, 16 sprite color codes
  169.  *
  170.  * Bit 0 = RED, Bit 1 = GREEN, Bit 2 = BLUE
  171.  *
  172.  */
  173.  
  174. void cosmica_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  175. {
  176.     int i;
  177.  
  178.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  179.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  180.  
  181.     for (i = 0;i < Machine->drv->total_colors;i++)
  182.     {
  183.         *(palette++) = 0xff * ((i >> 0) & 1);
  184.         *(palette++) = 0xff * ((i >> 1) & 1);
  185.         *(palette++) = 0xff * ((i >> 2) & 1);
  186.     }
  187.  
  188.  
  189.     for (i = 0;i < TOTAL_COLORS(0)/2;i++)
  190.     {
  191.         COLOR(0,i)                     =  * color_prom          & 0x07;
  192.         COLOR(0,i+(TOTAL_COLORS(0)/2)) = (*(color_prom++) >> 4) & 0x07;
  193.     }
  194.  
  195.  
  196.     map_color = panic_map_color;
  197. }
  198.  
  199.  
  200. /*
  201.  * Cosmic guerilla table setup
  202.  *
  203.  * Use AA for normal, FF for Full Red
  204.  * Bit 0 = R, bit 1 = G, bit 2 = B, bit 4 = High Red
  205.  *
  206.  * It's possible that the background is dark gray and not black, as the
  207.  * resistor chain would never drop to zero, Anybody know ?
  208.  *
  209.  */
  210.  
  211. void cosmicg_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  212. {
  213.     int i;
  214.  
  215.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  216.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  217.  
  218.     for (i = 0;i < Machine->drv->total_colors;i++)
  219.     {
  220.         if (i > 8) *(palette++) = 0xff;
  221.         else *(palette++) = 0xaa * ((i >> 0) & 1);
  222.  
  223.         *(palette++) = 0xaa * ((i >> 1) & 1);
  224.         *(palette++) = 0xaa * ((i >> 2) & 1);
  225.     }
  226.  
  227.  
  228.     map_color = cosmicg_map_color;
  229. }
  230.  
  231. /**************************************************/
  232. /* Magical Spot 2/Devil Zone specific routines    */
  233. /*                                                  */
  234. /* 16 colors, 8 sprite color codes                  */
  235. /**************************************************/
  236.  
  237. void magspot2_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  238. {
  239.     int i;
  240.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  241.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  242.  
  243.  
  244.     for (i = 0;i < Machine->drv->total_colors;i++)
  245.     {
  246.         if ((i & 0x09) == 0x08)
  247.             *(palette++) = 0xaa;
  248.          else
  249.             *(palette++) = 0xff * ((i >> 0) & 1);
  250.  
  251.         *(palette++) = 0xff * ((i >> 1) & 1);
  252.         *(palette++) = 0xff * ((i >> 2) & 1);
  253.     }
  254.  
  255.  
  256.     for (i = 0;i < TOTAL_COLORS(0);i++)
  257.     {
  258.         COLOR(0,i) = *(color_prom++) & 0x0f;
  259.     }
  260.  
  261.  
  262.     map_color = magspot2_map_color;
  263. }
  264.  
  265.  
  266. WRITE_HANDLER( nomnlnd_background_w )
  267. {
  268.     nomnlnd_background_on = data;
  269. }
  270.  
  271.  
  272. WRITE_HANDLER( cosmica_flipscreen_w )
  273. {
  274.     if (data != flipscreen)
  275.     {
  276.         flipscreen = data;
  277.  
  278.         refresh_tmpbitmap = 1;
  279.     }
  280. }
  281.  
  282.  
  283. WRITE_HANDLER( cosmica_videoram_w )
  284. {
  285.     int i,x,y,col;
  286.  
  287.     videoram[offset] = data;
  288.  
  289.     y = offset / 32;
  290.     x = 8 * (offset % 32);
  291.  
  292.     col = Machine->pens[map_color(x, y)];
  293.  
  294.     for (i = 0; i < 8; i++)
  295.     {
  296.         if (flipscreen)
  297.             plot_pixel(tmpbitmap, 255-x, 255-y, (data & 0x80) ? col : Machine->pens[0]);
  298.         else
  299.             plot_pixel(tmpbitmap,     x,     y, (data & 0x80) ? col : Machine->pens[0]);
  300.  
  301.         x++;
  302.         data <<= 1;
  303.     }
  304. }
  305.  
  306.  
  307. void cosmicg_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  308. {
  309.     if (refresh_tmpbitmap)
  310.     {
  311.         int offs;
  312.  
  313.         for (offs = 0; offs < videoram_size; offs++)
  314.         {
  315.             cosmica_videoram_w(offs, videoram[offs]);
  316.         }
  317.  
  318.         refresh_tmpbitmap = 0;
  319.     }
  320.  
  321.     copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  322. }
  323.  
  324.  
  325. void panic_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  326. {
  327.     int offs;
  328.  
  329.  
  330.     cosmicg_vh_screenrefresh(bitmap, full_refresh);
  331.  
  332.  
  333.     /* draw the sprites */
  334.  
  335.     for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  336.     {
  337.         if (spriteram[offs] != 0)
  338.         {
  339.             int code,bank,flipy;
  340.  
  341.             /* panic_remap_sprite_code sprite number to my layout */
  342.  
  343.             code = panic_remap_sprite_code[(spriteram[offs] & 0x3F)][0];
  344.             bank = panic_remap_sprite_code[(spriteram[offs] & 0x3F)][1];
  345.             flipy = spriteram[offs] & 0x40;
  346.  
  347.             if((code==0) && (bank==0))
  348.                 logerror("remap failure %2x\n",(spriteram[offs] & 0x3F));
  349.  
  350.             /* Switch Bank */
  351.  
  352.             if(spriteram[offs+3] & 0x08) bank=1;
  353.  
  354.             if (flipscreen)
  355.             {
  356.                 flipy = !flipy;
  357.             }
  358.  
  359.             drawgfx(bitmap,Machine->gfx[bank],
  360.                     code,
  361.                     7 - (spriteram[offs+3] & 0x07),
  362.                     flipscreen,flipy,
  363.                     256-spriteram[offs+2],spriteram[offs+1],
  364.                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  365.         }
  366.     }
  367. }
  368.  
  369.  
  370. void cosmica_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  371. {
  372.     int offs;
  373.  
  374.  
  375.     cosmicg_vh_screenrefresh(bitmap, full_refresh);
  376.  
  377.  
  378.     /* draw the sprites */
  379.  
  380.     for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  381.     {
  382.         if (spriteram[offs] != 0)
  383.         {
  384.             int code, color;
  385.  
  386.             code  = ~spriteram[offs  ] & 0x3f;
  387.             color = ~spriteram[offs+3] & 0x0f;
  388.  
  389.             if (spriteram[offs] & 0x80)
  390.             {
  391.                 /* 16x16 sprite */
  392.  
  393.                 drawgfx(bitmap,Machine->gfx[0],
  394.                         code,
  395.                         color,
  396.                         0,0,
  397.                         256-spriteram[offs+2],spriteram[offs+1],
  398.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  399.             }
  400.             else
  401.             {
  402.                 /* 32x32 sprite */
  403.  
  404.                 drawgfx(bitmap,Machine->gfx[1],
  405.                         code >> 2,
  406.                         color,
  407.                         0,0,
  408.                         256-spriteram[offs+2],spriteram[offs+1],
  409.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  410.             }
  411.         }
  412.     }
  413. }
  414.  
  415.  
  416. void magspot2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  417. {
  418.     int offs;
  419.  
  420.  
  421.     cosmicg_vh_screenrefresh(bitmap, full_refresh);
  422.  
  423.  
  424.     /* draw the sprites */
  425.  
  426.     for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  427.     {
  428.         if (spriteram[offs] != 0)
  429.         {
  430.             int code, color;
  431.  
  432.             code  = ~spriteram[offs  ] & 0x3f;
  433.             color = ~spriteram[offs+3] & 0x07;
  434.  
  435.             if (spriteram[offs] & 0x80)
  436.             {
  437.                 /* 16x16 sprite */
  438.  
  439.                 drawgfx(bitmap,Machine->gfx[0],
  440.                         code,
  441.                         color,
  442.                         0,0,
  443.                         256-spriteram[offs+2],spriteram[offs+1],
  444.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  445.             }
  446.             else
  447.             {
  448.                 /* 32x32 sprite */
  449.  
  450.                 drawgfx(bitmap,Machine->gfx[1],
  451.                         code >> 2,
  452.                         color,
  453.                         0,0,
  454.                         256-spriteram[offs+2],spriteram[offs+1],
  455.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  456.             }
  457.         }
  458.     }
  459. }
  460.  
  461.  
  462. void nomnlnd_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  463. {
  464.     int offs;
  465.  
  466.  
  467.     magspot2_vh_screenrefresh(bitmap, full_refresh);
  468.  
  469.  
  470.     if (nomnlnd_background_on)
  471.     {
  472.         // draw trees
  473.  
  474.         static UINT8 water_animate=0;
  475.  
  476.         water_animate++;
  477.  
  478.         for(offs=0;offs<2;offs++)
  479.         {
  480.             int code,x,y;
  481.  
  482.             x = nomnlnd_tree_positions[offs][0];
  483.             y = nomnlnd_tree_positions[offs][1];
  484.  
  485.             if (flipscreen)
  486.             {
  487.                 x = 223 - x;
  488.                 y = 223 - y;
  489.                 code = 2 + offs;
  490.             }
  491.             else
  492.             {
  493.                 code = offs;
  494.             }
  495.  
  496.             drawgfx(bitmap,Machine->gfx[2],
  497.                     code,
  498.                     8,
  499.                     0,0,
  500.                     x,y,
  501.                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  502.         }
  503.  
  504.         // draw water
  505.  
  506.         for(offs=0;offs<4;offs++)
  507.         {
  508.             int x,y;
  509.  
  510.             x = nomnlnd_water_positions[offs][0];
  511.             y = nomnlnd_water_positions[offs][1];
  512.  
  513.             if (flipscreen)
  514.             {
  515.                 x = 239 - x;
  516.                 y = 223 - y;
  517.             }
  518.  
  519.             drawgfx(bitmap,Machine->gfx[3],
  520.                     water_animate >> 3,
  521.                     9,
  522.                     0,0,
  523.                     x,y,
  524.                     &Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  525.         }
  526.     }
  527. }
  528.